package dragon.classloader;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;

public class DragonClassLoader extends ClassLoader {

    private String url; //需要加载的字节码文件的位置，绝对路径。

    public DragonClassLoader(String url) {
        this.url = url;
    }

    /**
     * 自定义类加载器推荐重写此方法，比较安全，
     * 重写 defineClass，对使用者能力要求较高。
     * <p>
     * 重写 findClass，以我个人的理解来说，就是根据 name，找到class文件的位置，
     * 然后读取该文件的数据，将其作为参数传入 defineClass 即可。
     * 当然了，还是需要自己动手，才能理解吧。
     */
    @Override
    public Class<?> findClass(String name) throws ClassNotFoundException {
        if (name.contains("dragon.classloader")) {
            name = name.replace('.', File.separatorChar);
            String filepath = this.url + name + ".class";
            System.out.println(filepath);

            //将该字节码文件读入内存中，这里我使用下面这个流来处理
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            //开始读取文件
            try (InputStream input = new BufferedInputStream(new FileInputStream(filepath))) {
                int len = 0;
                byte[] b = new byte[1024];
                while ((len = input.read(b)) != -1) {
                    output.write(b, 0, len);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            //将字节流转成字节数组
            byte[] data = output.toByteArray();
            return this.defineClass(null, data, 0, data.length);
        } else {
            return super.loadClass(name);
        }

    }

    /*@Override
    public Class<?> loadClass(String name) throws ClassNotFoundException {
        return this.findClass(name);
    }*/

}
